using FireStarterModeller.BO;
using Habanero.BO;
using NUnit.Framework;

namespace FirestarterModeller.Test.BO
{
    [TestFixture]
    public class TestAlternateKey : TestBase
    {
        [SetUp]
        public override void SetupTest()
        {
            //Runs every time that any testmethod is executed
            base.SetupTest();
        }

        [TestFixtureSetUp]
        public void TestFixtureSetup()
        {
            //Code that is executed before any test is run in this class. If multiple tests
            // are executed then it will still only be called once.
        }

        [TearDown]
        public override void TearDownTest()
        {
            //runs every time any testmethod is complete
            base.TearDownTest();
        }

        [Test]
        public void Test_InsertNewAlternateKeyInfo()
        {
            //---------------Set up test pack-------------------
            AlternateKeyInfo alternateKeyInfo = TestUtils.CreateUnsavedValidAlternateKeyInfo();

            //---------------Assert Precondition----------------
            Assert.IsTrue(alternateKeyInfo.Status.IsNew);

            //---------------Execute Test ----------------------
            alternateKeyInfo.Save();

            //---------------Test Result -----------------------
            Assert.IsFalse(alternateKeyInfo.Status.IsNew);
        }

        [Test]
        public void Test_InsertNewAlternateKeyInfo_Invalid()
        {
            //---------------Set up test pack-------------------
            AlternateKeyInfo alternateKeyInfo = new AlternateKeyInfo();

            //---------------Assert Precondition----------------
            Assert.IsTrue(alternateKeyInfo.Status.IsNew);

            //---------------Execute Test ----------------------
            try
            {
                alternateKeyInfo.Save();
                Assert.Fail("expected Err");
            }
            //---------------Test Result -----------------------
            catch (BusObjectInAnInvalidStateException ex)
            {
                StringAssert.Contains("Business Object Info I D' is a compulsory field and has no value", ex.Message);
                StringAssert.Contains("Message' is a compulsory field and has no value", ex.Message);
                StringAssert.Contains("Name' is a compulsory field and has no value", ex.Message);
            }
            Assert.IsTrue(alternateKeyInfo.Status.IsNew);
        }

        [Test]
        public void Test_DeleteAlternateKeyInfo()
        {
            //---------------Set up test pack-------------------
            AlternateKeyInfo alternateKeyInfo = TestUtils.CreateSavedAlternateKeyInfo();

            //---------------Assert Precondition----------------
            Assert.IsFalse(alternateKeyInfo.Status.IsNew);
            string message;
            Assert.IsTrue(alternateKeyInfo.IsDeletable(out message));

            //---------------Execute Test ----------------------
            alternateKeyInfo.Delete();
            alternateKeyInfo.Save();

            //---------------Test Result -----------------------  
            Assert.IsTrue(alternateKeyInfo.Status.IsNew);
            Assert.IsTrue(alternateKeyInfo.Status.IsDeleted);
        }

        [Test]
        public void Test_UpdateAlternateKeyInfo()
        {
            //---------------Set up test pack-------------------
            AlternateKeyInfo alternateKeyInfo = TestUtils.CreateSavedAlternateKeyInfo();

            //---------------Assert Precondition----------------
            Assert.IsFalse(alternateKeyInfo.Status.IsNew);
            string message;
            Assert.IsTrue(alternateKeyInfo.IsEditable(out message));

            //---------------Execute Test ----------------------
            alternateKeyInfo.IgnoreIfNull = false;
            alternateKeyInfo.Generated = true;
            alternateKeyInfo.Message = TestUtils.GetRandomString();
            alternateKeyInfo.Name = TestUtils.GetRandomString();
            
            alternateKeyInfo.Save();

            //---------------Test Result -----------------------
            Assert.IsFalse(alternateKeyInfo.Status.IsNew);
        }

        [Test]
        public void Test_LoadAlternateKeyInfo()
        {
            //---------------Set up test pack-------------------
            AlternateKeyInfo alternateKeyInfo = TestUtils.CreateSavedAlternateKeyInfo();
            BusinessObjectManager.Instance.ClearLoadedObjects();

            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            AlternateKeyInfo loadedAlternateKeyInfo = Broker.GetBusinessObject<AlternateKeyInfo>(alternateKeyInfo.ID);

            //---------------Test Result -----------------------  
            Assert.IsFalse(loadedAlternateKeyInfo.Status.IsNew);
            Assert.AreEqual(loadedAlternateKeyInfo.ID, alternateKeyInfo.ID);
            //TODO: When not using memory db Assert.AreNotSame(loadedBusinessObjectInfo, businessObjectInfo);
        }

        [Test]
        public void Test_GetKeyProperties()
        {
            //---------------Set up test pack-------------------

            AlternateKeyInfo alternateKeyInfo = TestUtils.CreateSavedAlternateKeyInfo();
            AlternateKeyPropertyInfo alternateKeyPropertyInfo = TestUtils.CreateSavedAlternateKeyPropertyInfo(alternateKeyInfo);
            BusinessObjectManager.Instance.ClearLoadedObjects();

            //---------------Assert Precondition----------------
            Assert.IsFalse(alternateKeyInfo.Status.IsNew);
            Assert.AreEqual(1, alternateKeyInfo.KeyProperties.Count);

            //---------------Execute Test ----------------------
            AlternateKeyPropertyInfo loadedAlternateKeyPropertyInfo = alternateKeyInfo.KeyProperties[0];

            //---------------Test Result -----------------------
            Assert.AreEqual(alternateKeyPropertyInfo.ID, loadedAlternateKeyPropertyInfo.ID);

        }
    }
}
